package com.ohos.connect.devicecloud.mqtt.modular.coap.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.ohos.connect.devicecloud.common.exception.CommonException;
import com.ohos.connect.devicecloud.iot.api.DeviceApi;
import com.ohos.connect.devicecloud.iot.model.dto.*;
import com.ohos.connect.devicecloud.iot.model.dto.deviceactive.DeviceActiveDTO;
import com.ohos.connect.devicecloud.iot.model.dto.deviceinfosync.DeviceInfoSyncDTO;
import com.ohos.connect.devicecloud.iot.model.vo.*;
import com.ohos.connect.devicecloud.iot.model.vo.deviceactive.DeviceActiveVO;
import com.ohos.connect.devicecloud.mqtt.modular.coap.constant.CoapOptionConstant;
import com.ohos.connect.devicecloud.mqtt.modular.coap.constant.HttpUriConstant;
import com.ohos.connect.devicecloud.mqtt.core.model.dto.CoapToHttpDTO;
import com.ohos.connect.devicecloud.mqtt.core.model.vo.CoapToHttpVO;
import com.ohos.connect.devicecloud.mqtt.modular.coap.service.CoapService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class CoapServiceImpl implements CoapService {

    @Resource
    private DeviceApi deviceApi;

    @Value("${ums.coap.address}")
    private String coapAddress = "127.0.0.1:8789/coapApi/v1/cmd";

    @Override
    public CoapToHttpVO coapToHttpMethod(CoapToHttpDTO coapToHttpDTO) {
        log.info("Coap to Http With url: {}",coapToHttpDTO.getUrl());
        log.info("Coap to Http With method: {}",coapToHttpDTO.getMethod());
        log.info("Coap to Http With body: {}",coapToHttpDTO.getBody());
        log.info("Coap to Http With option: {}", JSON.toJSONString(coapToHttpDTO.getOption()));

        HashMap<String,Object> option = coapToHttpDTO.getOption();
        if(ObjectUtil.isEmpty(option) || ObjectUtil.isNull(option.get(CoapOptionConstant.SEQ_NUM_ID))){
            throw new CommonException(CoapOptionConstant.SEQ_NUM_ID + "不能为空");
        }
        String seqNumId = option.get(CoapOptionConstant.SEQ_NUM_ID).toString();

        CoapToHttpVO coapToHttpVO = new CoapToHttpVO();

        if(HttpUriConstant.MATCH_PSK.equals(coapToHttpDTO.getUrl())){
            JSONObject bodyObj = new JSONObject(coapToHttpDTO.getBody());
            DevicePskDTO devicePskDTO = BeanUtil.toBean(bodyObj, DevicePskDTO.class);
            DevicePskVO devicePskVO = deviceApi.exchangeDeviceSn(devicePskDTO);
            coapToHttpVO.setBody((new JSONObject(devicePskVO)).toString());
        }

        if(HttpUriConstant.ACTIVATE.equals(coapToHttpDTO.getUrl())){
            JSONObject bodyObj = new JSONObject(coapToHttpDTO.getBody());
            DeviceActiveDTO deviceActiveDTO = BeanUtil.toBean(bodyObj, DeviceActiveDTO.class);
            DeviceActiveVO deviceActiveVO = deviceApi.activeDevice(deviceActiveDTO);
            coapToHttpVO.setBody((new JSONObject(deviceActiveVO)).toString());
        }

        if(HttpUriConstant.LOGIN.equals(coapToHttpDTO.getUrl())){
            JSONObject bodyObj = new JSONObject(coapToHttpDTO.getBody());
            DeviceLoginDTO deviceLoginDTO = BeanUtil.toBean(bodyObj, DeviceLoginDTO.class);
            DeviceLoginVO deviceLoginVO = deviceApi.loginDevice(deviceLoginDTO);
            coapToHttpVO.setBody((new JSONObject(deviceLoginVO)).toString());
        }

        if(HttpUriConstant.DEVICE_INFO_SYNC.equals(coapToHttpDTO.getUrl())){
            JSONArray bodyObjArray = new JSONArray(coapToHttpDTO.getBody());

            List<DeviceInfoSyncDTO> deviceInfoSyncDTOList = new ArrayList<>();
            for(Object obj : bodyObjArray){
                DeviceInfoSyncDTO deviceInfoSyncDTO = BeanUtil.toBean(obj,DeviceInfoSyncDTO.class);
                deviceInfoSyncDTOList.add(deviceInfoSyncDTO);
            }
            DeviceInfoSyncVO deviceInfoSyncVO = deviceApi.syncDeviceInfo(deviceInfoSyncDTOList);
            coapToHttpVO.setBody((new JSONObject(deviceInfoSyncVO)).toString());
        }

        if(HttpUriConstant.DEVICE_REVOKE.equals(coapToHttpDTO.getUrl())){
            JSONObject bodyObj = new JSONObject(coapToHttpDTO.getBody());
            DeviceRevokeDTO deviceRevokeDTO = BeanUtil.toBean(bodyObj,DeviceRevokeDTO.class);
            DeviceRevokeVO deviceRevokeVO = deviceApi.deviceRevoke(deviceRevokeDTO);
            coapToHttpVO.setBody((new JSONObject(deviceRevokeVO)).toString());
        }

        if(HttpUriConstant.DEVICE_AUTH_CODE.equals(coapToHttpDTO.getUrl())){
            JSONObject bodyObj = new JSONObject(coapToHttpDTO.getBody());
            DeviceAuthCodeDTO deviceAuthCodeDTO = BeanUtil.toBean(bodyObj,DeviceAuthCodeDTO.class);
            DeviceAuthCodeVO deviceAuthCodeVO = deviceApi.deviceAuthCode(deviceAuthCodeDTO);
            coapToHttpVO.setBody((new JSONObject(deviceAuthCodeVO)).toString());
        }

        if(HttpUriConstant.DEVICE_HEART_BEAT.equals(coapToHttpDTO.getUrl())){
            JSONObject bodyObj = new JSONObject(coapToHttpDTO.getBody());
            DeviceHeartBeatDTO deviceHeartBeatDTO = BeanUtil.toBean(bodyObj,DeviceHeartBeatDTO.class);
            DeviceHeartBeatVO deviceHeartBeatVO = deviceApi.deviceHeartBeat(deviceHeartBeatDTO);
            coapToHttpVO.setBody((new JSONObject(deviceHeartBeatVO)).toString());
        }

        if(HttpUriConstant.DEVICE_DATA.equals(coapToHttpDTO.getUrl())){
            JSONArray bodyObjArray = new JSONArray(coapToHttpDTO.getBody());

            List<DeviceDataInfoDTO> deviceDataInfoDTOList = new ArrayList<>();
            for(Object obj : bodyObjArray){
                DeviceDataInfoDTO deviceDataInfoDTO = BeanUtil.toBean(obj,DeviceDataInfoDTO.class);
                deviceDataInfoDTOList.add(deviceDataInfoDTO);
            }
            DeviceDataVO deviceDataVO = deviceApi.deviceDataUpload(deviceDataInfoDTOList);
            coapToHttpVO.setBody((new JSONObject(deviceDataVO)).toString());


        }

        HashMap<String,Object> optionResult = new HashMap<>();
        optionResult.put(CoapOptionConstant.SEQ_NUM_ID,seqNumId);
        coapToHttpVO.setOption(optionResult);

        log.info("Coap to Http return : {}", JSON.toJSONString(coapToHttpVO));

        return coapToHttpVO;
    }

    @Override
    public CoapToHttpVO httpToCoapMethod(CoapToHttpDTO coapToHttpDTO) {
        CoapToHttpVO coapToHttpVO = new CoapToHttpVO();
        sendPostToCoap(coapToHttpDTO);

        return coapToHttpVO;
    }

    private void sendPostToCoap(CoapToHttpDTO coapToHttpDTO) {

        RestTemplate restTemplate = new RestTemplate();
        // 创建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 创建请求体（这里使用了一个简单的Map，实际中你可能会使用一个DTO对象）
        Map<String, String> requestBody = new HashMap<>();
        requestBody.put("key1", "value1");
        requestBody.put("key2", "value2");

        // 将请求头和请求体包装到HttpEntity中
        HttpEntity<CoapToHttpDTO> request = new HttpEntity<>(coapToHttpDTO, headers);

        // 发送POST请求
        ResponseEntity<Object> response = restTemplate.postForEntity(coapAddress, request, Object.class);

        // 处理响应
        if (response.getStatusCode().is2xxSuccessful()) {
            System.out.println("Response: " + response.getBody());
        } else {
            System.err.println("Request failed with status code: " + response.getStatusCode());
        }
    }


}
